

import LayerManager from "./LayerManager"
import LayerInfo from "./LayerInfo";
import { UIType, MANAGER_LIST, LayerName } from "./UIType"
import Resolution from "../tools/Resolution";
import EventDispatcher from "../event/EventDispatcher";
import { GlobalIndex } from "../tools/Define";
import ResLoader from "../res/ResLoader";
import BaseScene from "../base/view/BaseScene";
import ResItem from "../res/ResItem";
import PoolManager from "../pool/PoolManager";


// 不受管理的管理器的个数，从后往前数。
let FIXED_NUM = 0;

export default class UIManager extends EventDispatcher {

    // 场景的根节点，也就是Canvas节点
    static CHANGE_SCENE: string = "ui_manager_change_scene"
    private root: cc.Node;
    private isLoading: boolean = false;
    //场景最底层的内容，不会进入UIManager管理器
    private container: cc.Node;
    //场景资源管理器
    private loader: ResLoader;

    private managers: LayerManager[] = [];

    private static ins: UIManager;

    // 需要做屏幕适配的场景名称对象
    private scaleSceneName = {};

    setScaleSceneName(name: {}) {
        this.scaleSceneName = name;
    }

    getLoader(): ResLoader {
        return this.loader;
    }

    find(path: string) {

        // cc.log(' this.root',this.root)
        return cc.find(path, this.root)
    }
    static instance(): UIManager {
        if (!UIManager.ins) {
            UIManager.ins = new UIManager();
        }
        return UIManager.ins;
    }

    private sceneName: string = "";

    constructor() {
        super();
        this.managers = [];
    }

    // 设置容器，也就是场景最底层的内容。
    setContainer(container: cc.Node) {
        this.container = container;
    }

    init(node: cc.Node, loader: ResLoader) {
        this.root = node;
        this.loader = loader;
        // if(this.scaleSceneName[this.sceneName]){
        Resolution.setRoot(node);
        // }
        for (let index = 0; index < MANAGER_LIST.length; index++) {
            const name = MANAGER_LIST[index];
            let HandlerModule = require(name);
            this.managers[index] = new HandlerModule();
            if (this.managers[index]) {
                let child = new cc.Node(LayerName[index]);
                child.width = node.width;
                child.height = node.height;
                child.zIndex = GlobalIndex.LAYER;
                this.root.addChild(child);
                this.managers[index].init(child);
            } else {
                cc.log("UIManager init error ", name);
            }
        }
    }


    /**
     * 进入一个场景时调用，替代引擎的提供的函数。
     * @param sceneName 场景名称
     * @param callback 场景加载回调
     */
    enterScene(sceneName: string, callback) {
        if (this.isLoading) {
            cc.log(+sceneName + "  is already load ");
            return;
        }
        cc.warn('enterScene ', sceneName)
        this.isLoading = true;
        this.sceneName = sceneName;
        let loader = new ResLoader();

        loader.preloadScene(sceneName, (err, item: ResItem) => {
            if (err) {
                return;
            }
            // cc.warn('--------------------------------------')
            //缓存 以免界面关闭场景资源被清理。
            item.getRes();
            // cc.warn("--------------------------------------- ",sceneName);
            // this.exitScene();

            // loader.addScene(sceneName,cc.SceneAsset,res);
            cc.director.loadScene(sceneName, (error, scene: cc.Scene) => {
                this.isLoading = false;
                if (error) {
                    cc.log("enterScene  error  ", error);
                    return;
                }

                // self.publish(UIManager.CHANGE_SCENE,sceneName);
                let node = scene.getChildByName("Canvas");
                if (node) {
                    // cc.warn(' loadScene ok ')
                    // Resolution.setRoot(node);
                    // let comp:BaseScene = node.getComponent(sceneName);
                    // if(comp){
                    //     comp.addLoader(loader);
                    // }
                    callback(null, node);
                } else {
                    callback("UIManager enterScene error component is null " + sceneName);
                }
            });
        });

    }


    /**
     * 
     * @param prefabName 预制体的名称
     * @param callback 加载后的回调。
     */
    getPrefab(prefabName: string, callback, isPool: boolean = false) {
        let resName = "";
        if (prefabName.indexOf("/") >= 0) {
            resName = prefabName;
            let list = prefabName.split("/");
            prefabName = list[list.length - 1];
        } else {
            resName = "prefabs/" + prefabName;
        }

        if (this.loader) {
            let node = PoolManager.instance().get(resName);
            if (node) {
                // cc.log(' getPrefab have view ',resName)
                callback(null, node);
            } else {
                this.loader.loadRes(resName, cc.Prefab,
                    (err, item: ResItem) => {
                        if (err) {
                            callback(" UIManager getComponent err " + err);
                            return;
                        }
                        let node = null;
                        if (isPool) {
                            PoolManager.instance().init(resName, item, 1);
                            node = PoolManager.instance().get(resName);
                        }else{
                            node = cc.instantiate(item.getRes())
                        }
                        if (node) {
                            callback(null, node);
                        } else {
                            callback("node is null");
                        }
                    });
            }

        } else {
            callback("loader is null");
        }
    }
    //获取当前场景下的资源管理器，场景销毁时自动清理。
    // getLoader(){
    //     return ResLoader.instance().getCustomLoader();
    // }

    exitScene() {
        this.managers.forEach(manager => {
            manager.clear();
        });
        this.managers = [];
    }

    // 加入到栈结构的管理器中
    pushView(layer,isPool:boolean = false) {
        if (layer) {
            let manager = this.managers[UIType.LAYER];
            if (!manager) {
                return;
            }

            layer.setUIType(UIType.LAYER);
            manager.pushView(new LayerInfo(layer, 0,isPool));

            // if (manager.count() == 1) {
            //     this.publish(MainEventName.PUSH_VIEW);
            // }
        }
    }

    // 加入到栈结构的管理器中
    // showView(layer){
    //     if(layer){
    //         layer.setUIType(UIType.LAYER);
    //         this.managers[UIType.LAYER].pushView(new LayerInfo(layer,0));
    //     }
    // }
    /**
     * 
     * @param layer 添加toastLayer。
     */
    pushToast(layer) {
        if (layer && this.managers[UIType.TOAST]) {
            layer.setUIType(UIType.TOAST);
            this.managers[UIType.TOAST].pushView(new LayerInfo(layer));
        }
    }
    pushGuide(layer) {
        if (layer && this.managers[UIType.GUIDE]) {
            layer.setUIType(UIType.GUIDE);
            this.managers[UIType.GUIDE].pushView(new LayerInfo(layer));
        }
    }
    // // 加入到队列结构的管理器中
    // addView(layer,priority: number = 0){
    //     if(layer &&  this.managers[UIType.QUEUE]){
    //         layer.setUIType(UIType.QUEUE);
    //         this.managers[UIType.QUEUE].pushView(new LayerInfo(layer,priority));
    //     }
    // }

    /**
     * 此方法用于关闭界面，为了兼容Android的back键 所以layer有为null的情况。
     * @param layer 
     */
    popView(layer?) {
        cc.log(" popView ");
        if (layer) {
            let type: UIType = layer.getUIType();
            let manger = this.managers[type];
            if (!manger) {
                return;
            }
            if (manger) {
                manger.popView(layer);
            }

        } else {
            for (let index = this.managers.length - FIXED_NUM; index >= 0; index--) {
                const manager = this.managers[index];
                if (manager && manager.popView(layer)) {
                    break;
                }
            }
        }
    }

    // 删除指定的界面
    // deleteView(layer){
    //     if(layer){
    //         let type: UIType = layer.getUIType();
    //         let manger = this.managers[type];
    //         manger.deleteView(layer.node);           
    //     }
    // }

    getManager(type: UIType) {
        return this.managers[type];
    }

    // showBlock(layer){
    //     if(layer &&  this.managers[UIType.LOADING]){
    //        this.managers[UIType.LOADING].pushView(new LayerInfo(layer));
    //     }        
    // }

    // pushLogout(layer){
    //     if(layer &&  this.managers[UIType.LOGOUT]){
    //         this.managers[UIType.LOGOUT].pushView(new LayerInfo(layer));
    //     }       
    // }

    getFillingScale(mode = 0) {
        let node = this.root
        if (!node) {
            cc.error(`no root`);
            return 1.0;
        }

        let designSz: cc.Size = Resolution.designSize;
        let ret = 1.0;
        let canvas = cc.Canvas.instance;

        if (canvas) {
            if (mode == 1 || (mode == 0 && canvas.fitHeight)) {
                ret = node.width / designSz.width;
            } else if (mode == 2 || (mode == 0 && canvas.fitWidth)) {
                ret = node.height / designSz.height;
            } else {
                cc.warn(`incorrect fit selection wide=${canvas.fitWidth} high=${canvas.fitHeight}`);
            }
        } else {
            cc.warn(`cc.Canvas.instance is NULL`);
        }
        return ret;
    }

    getRealSize() {
        return this.root.getContentSize();
    }
}
